/*
 * @Descripttion: 
 * @version: 
 * @Author: TT
 * @Date: 2022-12-05 10:32:05
 * @LastEditors: TT
 * @LastEditTime: 2023-03-15 21:42:56
 */

import 'dart:math';
import 'package:extended_image/extended_image.dart';
import 'package:flutter/foundation.dart';
import 'package:flutter/material.dart';
import 'package:extended_image_library/extended_image_library.dart';

typedef DoubleClickAnimationListener = void Function();

class ExtendedImageWidget {
  static Widget createbannerimage({
    /// 图片字节流
    Uint8List? bytes,

    /// 图片File
    File? imagefile,

    /// 网络图片地址
    String? imageurl,
    bool isgesture = false,
    AnimationController? doubleClickAnimationController,
    String? herostr,
    BoxFit? fit,
    double? width,
    double? height,
    BoxBorder? border,
    BorderRadius? borderRadius,
    BoxShape? shape,
    AnimationController? animationController,
    bool? cache = true,
    String? imageCacheName,
  }) {
    Widget child = Container();
    child = LayoutBuilder(
      builder: ((p0, p1) {
        Widget image = Container();
        Size size = Size(p1.maxWidth, p1.maxHeight);
        if (bytes != null) {
          image = ExtendedImage.memory(
            bytes,
            mode:
                isgesture ? ExtendedImageMode.gesture : ExtendedImageMode.none,
            width: width,
            border: border,
            borderRadius: borderRadius,
            height: height,
            shape: shape,
            loadStateChanged: isgesture
                ? null
                : (state) {
                    return configLoadStateChange(
                      state: state,
                      width: width,
                      height: height,
                    );
                  },
            initGestureConfigHandler: (ExtendedImageState state) {
              return initGestureConfighandler(
                state: state,
                size: size,
              );
            },
            onDoubleTap: (ExtendedImageGestureState state) {
              configDoubleTap(
                state: state,
                size: size,
                isgesture: isgesture,
                doubleClickAnimationController: doubleClickAnimationController,
              );
            },
            cacheRawData: true,
            fit: fit,
          );
        } else if (imagefile != null) {
          image = ExtendedImage.file(
            imagefile,
            mode:
                isgesture ? ExtendedImageMode.gesture : ExtendedImageMode.none,
            width: width,
            height: height,
            border: border,
            shape: shape,
            borderRadius: borderRadius,
            initGestureConfigHandler: (ExtendedImageState state) {
              return initGestureConfighandler(
                state: state,
                size: size,
              );
            },
            onDoubleTap: (ExtendedImageGestureState state) {
              configDoubleTap(
                state: state,
                size: size,
                isgesture: isgesture,
                doubleClickAnimationController: doubleClickAnimationController,
              );
            },
            cacheRawData: true,
            fit: fit,
          );
        } else if (imageurl != null) {
          image = ExtendedImage.network(
            imageurl,
            mode:
                isgesture ? ExtendedImageMode.gesture : ExtendedImageMode.none,
            width: width,
            height: height,
            fit: fit,
            cache: cache!,
            imageCacheName: imageCacheName,
            border: border,
            shape: shape,
            borderRadius: borderRadius,
            initGestureConfigHandler: (state) {
              return initGestureConfighandler(
                state: state,
                size: size,
              );
            },
            onDoubleTap: (state) {
              configDoubleTap(
                state: state,
                size: size,
                isgesture: isgesture,
                doubleClickAnimationController: doubleClickAnimationController,
              );
            },
            cacheRawData: cache,
          );
        }
        return image;
      }),
    );

    if (herostr != null) {
      child = Hero(
        tag: herostr,
        child: child,
      );
    }
    return child;
  }

  static double? initScale({
    required Size imageSize,
    required Size size,
    double? initialScale,
  }) {
    final double n1 = imageSize.height / imageSize.width;
    final double n2 = size.height / size.width;
    if (n1 > n2) {
      final FittedSizes fittedSizes =
          applyBoxFit(BoxFit.contain, imageSize, size);
      final Size destinationSize = fittedSizes.destination;
      return size.width / destinationSize.width;
    } else if (n1 / n2 < 1 / 4) {
      final FittedSizes fittedSizes =
          applyBoxFit(BoxFit.contain, imageSize, size);
      final Size destinationSize = fittedSizes.destination;
      return size.height / destinationSize.height;
    }

    return initialScale;
  }

  /// 配置点击事件
  static initGestureConfighandler({
    required ExtendedImageState state,
    required Size size,
  }) {
    double? initialScale = 1.0;
    if (state.extendedImageInfo != null) {
      initialScale = initScale(
        size: size,
        initialScale: initialScale,
        imageSize: Size(
          state.extendedImageInfo!.image.width.toDouble(),
          state.extendedImageInfo!.image.height.toDouble(),
        ),
      );
    }
    return GestureConfig(
      inPageView: true,
      initialScale: initialScale!,
      maxScale: max(initialScale, 5.0),
      animationMaxScale: max(initialScale, 5.0),
      initialAlignment: InitialAlignment.center,
      cacheGesture: false,
    );
  }

  /// 配置双击点击事件
  static configDoubleTap({
    required ExtendedImageGestureState state,
    required Size size,
    bool isgesture = true,
    AnimationController? doubleClickAnimationController,
  }) {
    Animation<double>? doubleClickAnimation;
    late DoubleClickAnimationListener doubleClickAnimationListener;
    List<double> doubleTapScales = <double>[1.0, 2.0];
    if (isgesture && doubleClickAnimationController != null) {
      final Offset? pointerDownPosition = state.pointerDownPosition;
      final double? begin = state.gestureDetails!.totalScale;
      double end;
      doubleClickAnimationController.stop();
      doubleClickAnimationController.reset();
      if (begin == doubleTapScales[0]) {
        end = doubleTapScales[1];
      } else {
        end = doubleTapScales[0];
      }
      doubleClickAnimationListener = () {
        state.handleDoubleTap(
          scale: doubleClickAnimation!.value,
          doubleTapPosition: pointerDownPosition,
        );
      };
      doubleClickAnimation = doubleClickAnimationController.drive(
        Tween<double>(
          begin: begin,
          end: end,
        ),
      );
      doubleClickAnimation.addListener(
        doubleClickAnimationListener,
      );
      doubleClickAnimationController.forward();
    }
  }

  static configLoadStateChange({
    required ExtendedImageState state,
    double? width,
    double? height,
  }) {
    switch (state.extendedImageLoadState) {
      case LoadState.loading:
        return Image.asset(
          "assets/images/animationImage.gif",
          fit: BoxFit.scaleDown,
        );
      case LoadState.completed:
        return ExtendedRawImage(
          image: state.extendedImageInfo?.image,
          width: width,
          height: height,
        );
      default:
    }
  }
}
